# *-* coding=utf-8 *-*
import datetime
import json
import random

import face_api as face_api

encode_file_name = "webservice/encode.text"


def create_uuid():  # 生成唯一的图片的名称字符串，防止图片显示时的重名问题
    now_time = datetime.datetime.now().strftime("%Y%m%d%H%M%S")  # 生成当前时间
    random_num = random.randint(0, 100)  # 生成的随机整数n，其中0<=n<=100
    if random_num <= 10:
        random_num = str(0) + str(random_num)
    unique_num = str(now_time) + str(random_num)
    return unique_num


# 获取人脸位置
def get_faces_points(file_stream, hog=True):
    # Load the uploaded image file
    image = face_api.load_image_file(file_stream)
    if hog:
        # 使用这种方法相当快速，但不如CNN模型准确，也不能GPU加速。
        face_locations = face_api.face_locations(image)
        return json.dumps(face_locations)
    else:
        # 使用深度学习，CNN模型，更准确，可用GPU加速。
        face_locations = face_api.face_locations(image, number_of_times_to_upsample=0, model="cnn")
        return json.dumps(face_locations)

    # for face_location in face_locations:
    #     # Print the location of each face in this image
    #     top, right, bottom, left = face_location
    #
    #     # 截取面部并保存下来
    #     face_image = image[top:bottom, left:right]
    #     pil_image = Image.fromarray(face_image)
    #
    #     file_name = "static/cut_face/" + create_uuid() + ".jpg"
    #     pil_image.save(file_name)
    #     return str(top)+','+str(right)+','+str(bottom)+','+str(left)


# 获取图片面部数量
def get_faces_num(file_stream):
    # Load the uploaded image file
    image = face_api.load_image_file(file_stream)
    # 使用这种方法相当快速，但不如CNN模型准确，也不能GPU加速。
    face_locations = face_api.face_locations(image)
    # 使用深度学习，CNN模型，更准确，可用GPU加速。
    # face_locations = face_recognition.face_locations(image, number_of_times_to_upsample=0, model="cnn")
    return len(face_locations)


# 获取人脸68特征点
def get_face_landmark(file_stream):
    # Load the uploaded image file
    image = face_api.load_image_file(file_stream)
    face_landmarks = face_api.face_landmarks(image)

    return json.dumps(face_landmarks)
    # 将特征点标记到图片上
    # # Create a PIL imagedraw object so we can draw on the picture
    # pil_image = Image.fromarray(image)
    # d = ImageDraw.Draw(pil_image)
    # for face_landmarks in face_landmarks:
    #     # Let's trace out each facial feature in the image with a line!
    #     for facial_feature in face_landmarks.keys():
    #         d.line(face_landmarks[facial_feature], width=2)
    #         # d.point(face_landmarks[facial_feature], fill=(0, 255, 0))
    # file_name = "static/lamd_face/" + create_uuid() + ".jpg"
    # pil_image.save(file_name)
    # return file_name


# 获取人脸128维嵌入编码
def get_face_encode(file_stream):
    # Load the uploaded image file
    image = face_api.load_image_file(file_stream)
    encode = face_api.face_encodings(image, num_jitters=5)
    result = []
    for i in encode[0]:
        result.append(str(i))
    result = json.dumps(result)
    return result


# 获取人脸相似度
def get_face_sim(file_stream1, file_stream2):
    # Load the uploaded image file
    image1 = face_api.load_image_file(file_stream1)
    image2 = face_api.load_image_file(file_stream2)
    unknown_face_encode = face_api.face_encodings(image1, num_jitters=3)[0]
    know_face_encode = face_api.face_encodings(image2, num_jitters=3)[0]
    known_faces = [
        know_face_encode
    ]

    face_distances = face_api.face_distance(known_faces, unknown_face_encode)
    results = ''
    for i, face_distance in enumerate(face_distances):
        results = "{:.2}".format(face_distance)

    # results = face_api.compare_faces(known_faces, know_face_encode1)
    result = json.dumps(results)
    return result


# 是否是某人的脸
def get_face_name(file_stream):
    # Load the uploaded image file
    unknown_image = face_api.load_image_file(file_stream)
    # 人脸对齐

    unknown_face_encode = face_api.face_encodings(unknown_image)[0]

    # 读取已保存的面部模板
    know_face_encode = []

    encode_file = open(encode_file_name, "r", encoding='utf-8')
    # 按行读取每个 name 对应的 face_encode
    lines = encode_file.readlines()
    names = "姓名："
    for i in range(0, len(lines)):
        key_value = json.loads(lines[i], strict=False)
        for key in key_value:
            names = names + key + ",\t"
            value_encode = key_value[key]
            face_encode = []
            for number in value_encode:
                face_encode.append(float(number))
            know_face_encode.append(face_encode)

    encode_file.readline()
    encode_file.close()
    # 计算相似度
    distances = face_api.face_distance(know_face_encode, unknown_face_encode)
    sims = "结果："
    for distance in distances:
        sims = sims + "{:.2} ".format(distance) + ",\t"

    # num = min(results)
    # results.tostring()
    # names.index(num)
    return names + " \n" + sims


# 保存图片
def save_local(image_data):
    image_save = open("static/save_img/" + create_uuid() + '.jpg', 'wb')
    image_save.write(image_data)
    image_save.close()


# 保存 编码:人名
def face_regist(file_stream, name):
    # Load the uploaded image file
    image = face_api.load_image_file(file_stream)
    encode = face_api.face_encodings(image, None)
    result = []
    for i in encode[0]:
        result.append(str(i))

    new_dict = {name: result}

    json_str = json.dumps(new_dict, ensure_ascii=False)

    file = open(encode_file_name, "a", encoding='utf-8')
    file.write(json_str + '\n')
    file.close()
